﻿using DTcms.Core.Common.Emum;
using DTcms.Core.Common.Extensions;
using DTcms.Core.Common.Helper;
using DTcms.Core.DBFactory.Database;
using DTcms.Core.IServices;
using DTcms.Core.Model.ViewModels;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace DTcms.Core.Services
{
    /// <summary>
    /// 手机短信接口实现
    /// </summary>
    public class SmsService : BaseService, ISmsService
    {
        private readonly ISysConfigService _configService;
        public SmsService(IDbContextFactory contentFactory, ISysConfigService configService) : base(contentFactory) 
        {
            _configService = configService;
        }

        /// <summary>
        /// 发送短信
        /// </summary>
        public async Task<SmsResultDto> Send(SmsMessageDto modelDto, WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            _context = _contextFactory.CreateContext(writeAndRead);//连接数据库

            var model = await _configService.QueryByTypeAsync(ConfigType.SysConfig);
            if (model == null)
            {
                throw new ResponseException($"系统参数有误，请联系管理员");
            }
            var config = JsonHelper.ToJson<SysConfigDto>(model.JsonData);

            if (!config.SmsApiUrl.IsNotNullOrEmpty() || !config.SmsUserName.IsNotNullOrEmpty() || !config.SmsPassword.IsNotNullOrEmpty())
            {
                throw new ResponseException($"短信配置参数有误，请联系管理员");
            }
            //检查手机号码，如果超过2000则分批发送
            int sucCount = 0; //成功提交数量
            var resultModel = new SmsResultDto(); //错误消息
            string[] oldMobiles = modelDto.Mobiles.Split(',');
            int batch = oldMobiles.Length / 2000 + 1; //2000条为一批，求出分多少批
            for (int i = 0; i < batch; i++)
            {
                StringBuilder newMobiles = new StringBuilder();
                int sendCount = 0; //发送数量
                int maxLenght = (i + 1) * 2000; //循环最大的数
                //检测号码，忽略不合格的，重新组合
                for (int j = 0; j < oldMobiles.Length && j < maxLenght; j++)
                {
                    int arrNum = j + (i * 2000);
                    string pattern = @"^1\d{10}$";
                    string mobile = oldMobiles[arrNum].Trim();
                    Regex r = new Regex(pattern, RegexOptions.IgnoreCase); //正则表达式实例，不区分大小写
                    Match m = r.Match(mobile); //搜索匹配项
                    if (m != null)
                    {
                        sendCount++;
                        newMobiles.Append(mobile + ",");
                    }
                }
                //发送短信
                if (newMobiles.ToString().Length > 0)
                {
                    string sendUrl = $"{config.SmsApiUrl}?cmd=tx&pass={modelDto.Pass}&uid={config.SmsUserName}&pwd={MD5Helper.MD5Encrypt32(config.SmsPassword)}&mobile={newMobiles.ToString().TrimEnd(',')}&encode=utf8&content={System.Web.HttpUtility.UrlEncode(modelDto.Content)}";
                    var result = RequestHelper.Post(sendUrl, string.Empty, "application/x-www-form-urlencoded");
                    string[] strArr = result.Split(new string[] { "||" }, StringSplitOptions.None);
                    if (strArr[0] != "100")
                    {
                        resultModel.Code = strArr[0];
                        resultModel.Message = "提交失败：" + (strArr.Length > 1 ? strArr[1] : result);
                        continue;
                    }
                    sucCount += sendCount; //成功数量
                }
            }
            //返回状态
            if (sucCount > 0)
            {
                resultModel.Code = "100";
                resultModel.Message = $"成功提交{sucCount}号码，失败{(oldMobiles.Length - sucCount)}号码";
            }
            return resultModel;
        }

        /// <summary>
        /// 查询账户剩余短信数量
        /// </summary>
        public async Task<SmsResultDto> GetAccountQuantity(WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            var model = await _configService.QueryByTypeAsync(ConfigType.SysConfig);
            if (model == null)
            {
                throw new ResponseException($"系统参数设置有误，请联系管理员", ErrorCode.NotFound);
            }
            var config = JsonHelper.ToJson<SysConfigDto>(model.JsonData);

            if (!config.SmsApiUrl.IsNotNullOrEmpty() || !config.SmsUserName.IsNotNullOrEmpty() || !config.SmsPassword.IsNotNullOrEmpty())
            {
                throw new ResponseException($"短信配置参数有误，请联系管理员");
            }

            string sendUrl = $"{config.SmsApiUrl}?cmd=mm&uid={config.SmsUserName}&pwd={MD5Helper.MD5Encrypt32(config.SmsPassword)}";
            var result = RequestHelper.Post(sendUrl, string.Empty, "application/x-www-form-urlencoded");
            string[] resultArr = result.Split(new string[] { "||" }, StringSplitOptions.None);
            //返回状态
            var resultModel = new SmsResultDto();
            if (resultArr.Length > 1)
            {
                resultModel.Code = resultArr[0];
                resultModel.Message = resultArr[1];
            }
            else
            {
                resultModel.Code = "115";
                resultModel.Message = result;
            }
            return resultModel;
        }

        /// <summary>
        /// 查询已发送数量
        /// </summary>
        public async Task<SmsResultDto> GetSendQuantity(WriteRoRead writeAndRead = WriteRoRead.Read)
        {
            var model = await _configService.QueryByTypeAsync(ConfigType.SysConfig);
            if (model == null)
            {
                throw new ResponseException($"系统参数设置有误，请联系管理员", ErrorCode.NotFound);
            }
            var config = JsonHelper.ToJson<SysConfigDto>(model.JsonData);

            if (!config.SmsApiUrl.IsNotNullOrEmpty() || !config.SmsUserName.IsNotNullOrEmpty() || !config.SmsPassword.IsNotNullOrEmpty())
            {
                throw new ResponseException($"短信配置参数有误，请联系管理员");
            }

            string sendUrl = $"{config.SmsApiUrl}?cmd=se&uid={config.SmsUserName}&pwd={MD5Helper.MD5Encrypt32(config.SmsPassword)}";
            var result = RequestHelper.Post(sendUrl, string.Empty, "application/x-www-form-urlencoded");
            string[] resultArr = result.Split(new string[] { "||" }, StringSplitOptions.None);
            //返回状态
            var resultModel = new SmsResultDto();
            if (resultArr.Length > 1)
            {
                resultModel.Code = resultArr[0];
                resultModel.Message = resultArr[1];
            }
            else
            {
                resultModel.Code = "115";
                resultModel.Message = result;
            }
            return resultModel;
        }

    }
}
